\chapter{Structure of the OS}

We have identified the main parts of our operating system as follows:

\section{Process management unit}

When a new process is to be created, the system must create a Process Control Block (PCB) for it. This PCB is then placed into the ready queue, so that the new process can be scheduled and executed. 

When a process terminates, the system must deallocate its PCB and reclaim every resource that has been allocated to it.

\section{Scheduler}

The role of the scheduler is to allocate the CPU to processes, according to a given policy.

In our operating system, the processes will be scheduled using \textit{preemptive priority scheduling}. Each process has a priority level, located in its PCB. The scheduler always gives the CPU to the process in the ready queue with the highest priority, preempting the current executing process if it has a lower priority. If there are several processes with the highest priority in the ready queue, they are scheduled using Round Robin (RR), that is each process executes during a give time quantum and is then preempted to let one another execute.

\section{Dispatcher}

The dispacher allocates the processor to the process selected by the scheduler. So, it is responsible for doing context switches. It allocates the CPU by setting the Program Counter (PC) to the correct location in the program that is to be executed. This operation is the last step of loading the context of the next process to run.

\section{I/O systems}

We have three main I/O devices in our system, and all are mapped in memory.

The \textit{tty0} device communicates with the serial port and will be used to implement the text console.

The \textit{malta0} device controls the 8-character LCD display of the MALTA board.

The \textit{rtc0} device is a real time clock that stores the time of the day and can generate periodic interrupts. These interrupts will be used to implement the RR part of the scheduler.

\section{API}

The API is used by user programs to request the services of the kernel. The user programs see the API as a set of C functions. For example, a program that wants to create a process will need to use the API and cannot do that by itself or by accessing the kernel directly.

The API is then the only way for user programs to use the kernel functionalities and interact with the kernel datastructures. 

The API will include functions to manage processes, like changing the priority or terminating another process. There will also be functions to do I/O, message passing, process supervision...

\section{Message passing unit}

Our OS must provide message passing as the way of doing IPC (interprocess communication) in our system. This unit must then provide support for processes to send, receive and filter messages. 

%Each message has a type which is used by the receiving process to filter it. It must be possible to wait for a specific type of message.
%Each message has a type which is use by the receiving process to filter it. It must be possible to wait for a specific type of message.			

Each message has a priority, which is an integer number. The OS offers a way to filter messages using their priority.		

According to the requirements, only the receive operation can be blocking. When such a case happens, the blocking is done using interrupts and not busy waiting.

\section{Process supervision unit}

A process must be able to register itself as a supervisor of a set of other processes. It will then get some information when the supervised processes terminates, either normally or abnormally, and will be able to use it to perform its work.

This unit has then to provide a way to register a supervisor. It must also ensure that the information about the termination of a process is correctly passed to its registered supervisors.

\section{Dynamic memory management unit}

%[VW] I would recommend avoiding the word "module", because it is too implementation specific

The kernel must provide the possibility to allocate memory dynamically to processes. That way we do not need fixed size structures anymore in the kernel and the user programs.

This unit must then provide memory allocation as well as de-allocation and has to make sure that all the memory dynamically allocated to a process is given back when the latter terminates. The module will also provide a way to deal with out-of-memory situations.

The API will then be extended to allow user programs to use the module. 
